package club.hicode.daydayup.netty.tcp;

import club.hicode.daydayup.netty.udp.agent.CmdBO;
import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 服务端 channel
 *
 * @author LiuChunfu
 */
public class SimpleChatServerHandler extends SimpleChannelInboundHandler<String> {

    private static final String DELIMITER_FLAG = "$";

    /**
     * 一个线程安全的Set，可以自定义分组。一个关闭的Channel会自动从这个集合中移除，不需要手动维护。
     */
    public static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        // Broadcast a message to multiple Channels
        channels.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 加入" + DELIMITER_FLAG);
        channels.add(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();

        // Broadcast a message to multiple Channels
        channels.writeAndFlush("[SERVER] - " + incoming.remoteAddress() + " 离开" + DELIMITER_FLAG);
        //因为使用的是ChannelGroup，所以Channel会自动从上述集合中移除，不需要"channels.remove(ctx.channel());"
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String body) throws Exception {
        Channel incoming = ctx.channel();
        ObjectMapper mapper = new ObjectMapper();
        CmdBO<String, String> cmdBO = mapper.readValue(body, new TypeReference<CmdBO<String, String>>() {
        });
        System.out.println(DateUtil.now() + " 收到:" + body);
        cmdBO.setResult(DateUtil.now());
        String value = mapper.writeValueAsString(cmdBO) + "$";
        incoming.writeAndFlush(value);
        System.out.println(DateUtil.now() + " 回执:" + value);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println("SimpleChatClient:" + incoming.remoteAddress() + "在线");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel incoming = ctx.channel();
        System.out.println("SimpleChatClient:" + incoming.remoteAddress() + "掉线");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        Channel incoming = ctx.channel();
        System.out.println("SimpleChatClient:" + incoming.remoteAddress() + "异常");
        cause.printStackTrace();
        ctx.close();
    }
}